package com.vision.sales.sv.report;

import java.util.List;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

/**
 * Base class for all classes that will serve as data sources.
 * The class provides implementation for <tt>next()</tt> and
 * <tt>getFieldValue(JRField)</tt>. The class also provides a
 * <tt>sort(SortConfig[])</tt> method to sort the elements of its
 * backing data.
 *
 * @author Mark
 *
 * @param <T>
 */
public abstract class AbstractDataSource<T> implements JRDataSource {

	protected List<T> objects;
	protected int index;

	/**
	 *
	 * @param objects
	 */
	public AbstractDataSource(List<T> objects) {
		this.objects = objects;
		this.index = -1;
	}

	/**
	 * Returns true if the backing list of data is empty.
	 * Returns false otherwise.
	 *
	 * @return
	 */
	public boolean isEmpty() {
		return objects.isEmpty();
	}

	/**
	 * Calls <tt>getValue(T, String)</tt> to return the value of the field
	 * on the current object. Classes must override <tt>getValue(T, String)</tt>.
	 *
	 * @see JRDataSource#getFieldValue(JRField)
	 */
	public Object getFieldValue(JRField field) throws JRException {
		T object = objects.get(index);

		return getValue(object, field.getName());
	}

	/*
	 * (non-Javadoc)
	 * @see net.sf.jasperreports.engine.JRDataSource#next()
	 */
	public boolean next() throws JRException {
		return (objects != null && ++index < objects.size());
	}

	/**
	 * Implemented by subclasses to return the value of the field
	 * retrieved from the specified object.
	 *
	 * @param object
	 * @param fieldName
	 * @return
	 */
	public abstract Object getValue(T object, String fieldName);

	/**
	 * Returns the raw (uncoverted) value from the specified <tt>object</tt>
	 * which corresponds to <tt>fieldName</tt>. The default implementation invokes
	 * {@link #getValue(Object, String)}. This method is used in sorting the items
	 * in the data source.
	 *
	 * Subclasses must override this method to return the correct raw value.
	 *
	 * @param object
	 * @param fieldName
	 * @return
	 */
	public Object getRawValue(T object, String fieldName) {
		return getValue(object, fieldName);
	}

}
